﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using MVVM_CAD.Common;
using MVVM_CAD.Model;
using MVVM_CAD.Strategy;

namespace MVVM_CAD.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        #region Members
        public DrawingCanvas Canvas { get; set; }
        /// <summary>
        /// The <see cref="SceneManagerViewModel" /> property's name.
        /// </summary>
        public const string SceneManagerViewModelPropertyName = "SceneManagerViewModel";

        private SceneManagerViewModel _myProperty = null;

        /// <summary>
        /// Gets the SceneManagerViewModel property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public SceneManagerViewModel SceneManagerViewModel
        {
            get
            {
                return _myProperty;
            }

            set
            {
                if (_myProperty == value)
                {
                    return;
                }

                var oldValue = _myProperty;
                _myProperty = value;

                RaisePropertyChanged(SceneManagerViewModelPropertyName);
            }
        }

        #region DrawedFigures Property
        /// <summary>
        /// The <see cref="DrawedFigures" /> property's name.
        /// </summary>
        public const string DrawedFiguresPropertyName = "DrawedFigures";
        private ObservableCollection<IFigure> _drawedFigures;

        /// <summary>
        /// Gets the DrawedFigures property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<IFigure> DrawedFigures
        {
            get
            {
                return _drawedFigures;
            }
            set
            {
                if (_drawedFigures == value)
                {
                    return;
                }

                _drawedFigures = value;
                RaisePropertyChanged(DrawedFiguresPropertyName);
            }
        }

        #endregion
        #region SelectedFigure Property
        /// <summary>
        /// The <see cref="SelectedFigure" /> property's name.
        /// </summary>
        public const string SelectedFigurePropertyName = "SelectedFigure";

        private IFigure _selectedFigure = null;

        /// <summary>
        /// Gets the SelectedFigure property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public IFigure SelectedFigure
        {
            get
            {
                return _selectedFigure;
            }
            set
            {
                if (_selectedFigure == value)
                {
                    return;
                }
                _selectedFigure = value;
                RaisePropertyChanged(SelectedFigurePropertyName);
            }
        }
        #endregion
        /// <summary>
        /// The <see cref="Strategy" /> property's name.
        /// </summary>
        public const string StrategyPropertyName = "Strategy";

        private IStrategy _strategy = null;

        public IStrategy Strategy
        {
            get
            {
                return _strategy;
            }

            set
            {
                if (_strategy == value)
                {
                    return;
                }

                var oldValue = _strategy;
                _strategy = value;

                RaisePropertyChanged(StrategyPropertyName);
            }
        }

        #endregion

        #region Commands

        #region OnClicCommand
        private ICommand _onClicToolCommand = null;
        public ICommand OnClicToolCommand
        {
            get
            {
                return _onClicToolCommand ??
                       (_onClicToolCommand = new RelayCommand<MouseEventArgs>(StrategyPerformOnClic));
            }
        }

        private void StrategyPerformOnClic(MouseEventArgs e)
        {
            var point = new CustomPoint(e.GetPosition(Canvas).X, e.GetPosition(Canvas).Y);
            var figure = Strategy.PerformMouseLeftClicDownEvent(Canvas, point, null);
        
        }
        #endregion

        #region OnMoveCommand
        private ICommand _onMoveToolCommand = null;
        public ICommand OnMoveToolCommand
        {
            get
            {
                return _onMoveToolCommand ??
                       (_onMoveToolCommand = new RelayCommand<MouseEventArgs>(StrategyPerformOnMove));
            }
        }
        
        private void StrategyPerformOnMove(MouseEventArgs e)
        {
            if (Strategy == null) return;
            if (!e.LeftButton.HasFlag(MouseButtonState.Pressed)) return;
            var point = new CustomPoint(e.GetPosition(Canvas).X, e.GetPosition(Canvas).Y);
            var figure = Strategy.PerformMouseMoveEvent(Canvas, point);
        }
        #endregion

        #region SaveFileCommand

        private ICommand _saveSceneToolCommand = null;

        public ICommand SaveSceneToolCommand
        {
            get
            {
                return _saveSceneToolCommand ??
                    (_saveSceneToolCommand = new RelayCommand(() =>
                                                                  {
                                                                      SceneManagerViewModel =
                                                                          new SceneManagerViewModel(DrawedFigures, Canvas);
                                                                  }));
            }
        }
        #endregion

        #region MoveFigureCommands

        #region Move on X
        private ICommand _moveXCoordinateToolCommand;

        //public ICommand MoveXCoordinateToolCommand
        //{
        //    get
        //    {
        //        return _moveXCoordinateToolCommand ??
        //               (_moveXCoordinateToolCommand = new RelayCommand<string>(p => IncrementXCoordinateOfPointsInFigure(Convert.ToDouble(p))));
        //    }
        //}

        #endregion

        #region Move on Y
        private ICommand _moveYCoordinateToolCommand;

        //public ICommand MoveYCoordinateToolCommand
        //{
        //    get
        //    {
        //        return _moveYCoordinateToolCommand ??
        //               (_moveYCoordinateToolCommand = new RelayCommand<string>(p => IncrementYCoordinateOfPointsInFigure(Convert.ToDouble(p))));
        //    }
        //}

        #endregion
        #endregion

        #region ScaleFigureCommands

        private ICommand _scaleXToolCommand = null;

        //public ICommand ScaleToolCommand
        //{
        //    get
        //    {
        //        return _scaleXToolCommand ??
        //               (_scaleXToolCommand = new RelayCommand<string>(p => ScaleOnXSelectedFigure(Convert.ToDouble(p))));
        //    }
        //}

        #endregion


        #endregion

        #region Public Methods

        public void AddFigure(IFigure drawedFigure)
        {
            if (_drawedFigures.Contains(drawedFigure))
            {
                SelectedFigure = drawedFigure;
                return;
            }

            if (drawedFigure.DrawStatus.Equals(DrawStatus.Completed))
                DrawedFigures.Add(drawedFigure);
        }

        #endregion

        public MainViewModel()
        {
            //DrawingFigure = new List<IPoint>();
            Messenger.Default.Register<IStrategy>(this, s => Strategy = s);
        }

        //private void ScaleOnXSelectedFigure(double incremet)
        //{
        //    EraseSelectedObject();

        //}

        //public void IncrementXCoordinateOfPointsInFigure(double xIncrement)
        //{
        //    EraseSelectedObject();
        //    SelectedFigure.PointsCollection.ForEach(p => p.X = p.X + xIncrement);
        //    DrawSelectedObject();
        //}

        //public void IncrementYCoordinateOfPointsInFigure(double xIncrement)
        //{
        //    EraseSelectedObject();
        //    SelectedFigure.PointsCollection.ForEach(p => p.Y = p.Y + xIncrement);
        //    DrawSelectedObject();
        //}

        //private void DrawSelectedObject()
        //{
        //    SelectedFigure.PointsCollection.ForEach(p => p.Color = Colors.Red);
        //    FigureDrawer.DrawFigure(Canvas, SelectedFigure);
        //}

        //private void EraseSelectedObject()
        //{
        //    SelectedFigure.PointsCollection.ForEach(p => p.Color = Colors.White);
        //    FigureDrawer.DrawFigure(Canvas, SelectedFigure);
        //}

        //public void ScaleOnXCoordinate(double incremet)
        //{
        //    EraseSelectedObject();
        //    var vertices = SelectedFigure.PointsCollection.Where(p => p.IsVertex);
        //    vertices.ForEach(p => p.X = p.X*incremet);
        //    //Obtener a partir de la figura que esta seleccionada, la estrategia.
        //    //hacer un foreach de los puntos dibujando nuevamente, no modificar el primero.
        //    //Reemplazar la coleccion de puntos de la figura seleccionada, por la de la nueva figura.
        //}


    }
}